package com.example.service.Impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.common.enums.KeyEnum;
import com.example.mapper.MarkerMapper;
import com.example.mapper.ProjectMapper;
import com.example.mapper.TeamMapper;
import com.example.pojo.dto.MarkerDTO;
import com.example.pojo.entity.Admin;
import com.example.pojo.entity.Marker;
import com.example.pojo.entity.Project;
import com.example.pojo.vo.MarkerVO;
import com.example.service.AdminService;
import com.example.service.MarkerService;
import com.example.utils.AddressUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;


/**
 * TODO
 *
 * @author ding
 * @since 2024/5/31
 */
@Service
@DS("master")
public class MarkerServiceImpl extends ServiceImpl<MarkerMapper, Marker> implements MarkerService {

    @Autowired
    MarkerMapper markerMapper;

    @Autowired
    private AdminService adminService;

    @Autowired
    private ProjectMapper projectMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private TeamMapper teamMapper;

    /**
     * 新增地图标点
     */
    @Transactional
    public void add(Marker marker) {
        marker.setIsDeleted(0);
        marker.setVersion(0);
        String address = AddressUtils.getAddressByHttp(marker.getLng(), marker.getLat());
        marker.setAddress(address);
        //设置项目已标点
        projectMapper.update(new LambdaUpdateWrapper<Project>()
                .set(Project::getIsMarker, 1)
                .eq(Project::getId, marker.getProjectId()));
        markerMapper.insert(marker);
        redisTemplate.delete(KeyEnum.MARKER_INFO);
    }

    /**
     * 获得全部地图标点
     */
    public List<Marker> getAll(Integer userId) {
        Admin admin = adminService.selectById(userId);
        String key = KeyEnum.MARKER;

        QueryWrapper<Project> projectQueryWrapper = new QueryWrapper<>();
        // 根据当前用户的id，根据其团队id，获取项目id集合
        List<Integer> ids = null;
        if (admin.getTeamId() != null){
            projectQueryWrapper.eq("team_id", admin.getTeamId());
            ids = projectMapper.selectList(projectQueryWrapper)
                    .stream()
                    .map(Project::getId)
                    .collect(Collectors.toList());
        }
        QueryWrapper<Marker> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_deleted",0)
                .in(ObjectUtil.isNotEmpty(ids),"project_id", ids);

        List<Marker> markers = markerMapper.selectList(queryWrapper);

        return markers;
    }

    /**
     * 根据坐标点删除地图标点
     */
    @Transactional
    public void deleteByLngLat(Integer projectId) {
        //
        redisTemplate.delete(KeyEnum.MARKER_INFO);


        UpdateWrapper<Marker> queryWrapper = new UpdateWrapper<>();
        queryWrapper.eq("project_id", projectId);
        //设置项目未标点
        projectMapper.update(new LambdaUpdateWrapper<Project>()
                .set(Project::getIsMarker, 0)
                .eq(Project::getId, projectId));

        Marker marker = markerMapper.selectOne(queryWrapper);
        marker.setIsDeleted(1);
        markerMapper.updateById(marker);
    }

    /**
     * 根据项目id获取对应坐标点
     */
    public Marker getByProjectId(Integer projectId) {

        QueryWrapper<Marker> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("project_id",projectId)
                    .eq("is_deleted",0);
        return markerMapper.selectOne(queryWrapper);
    }

    /**
     * 获取全部数据，为ECharts传数据
     */
    public List<MarkerVO> getEChartData() {
        //从redis中获取标点相关数据
        List<MarkerVO> markerList = (List<MarkerVO>) redisTemplate.opsForValue().get(KeyEnum.MARKER_INFO);
        if(ObjectUtil.isEmpty(markerList)){
            List<MarkerVO> markerVOS = new ArrayList<>();
            List<Marker> markers = markerMapper.selectList(new LambdaQueryWrapper<Marker>());
            markers.forEach(marker -> {
                Project project = projectMapper.selectById(marker.getProjectId());
                MarkerVO markerVO = new MarkerVO();
                markerVO.setName(project.getName());
                Object[] value = new Object[5];
                value[0] = marker.getLng();
                value[1] = marker.getLat();
                value[2] = project.getBegin() + " - " + project.getEnd();
                if (ObjectUtil.isNotEmpty(project.getTeamId())){
                    value[3] = teamMapper.selectById(project.getTeamId()).getName();
                }else {
                    value[3] = "暂无施工队接取";
                }
                //为标点设置具体地址
                value[4] = marker.getAddress();
                markerVO.setValue(value);
                markerVOS.add(markerVO);
            });

            redisTemplate.opsForValue().set(KeyEnum.MARKER_INFO, markerVOS);
            return markerVOS;
        }else {
            return markerList;
        }
    }

    @Override
    public String getAddressByLngLat(MarkerDTO markerDTO) {
        return AddressUtils.getAddressByHttp(markerDTO.getLng(), markerDTO.getLat());
    }
}
